package com.smasher.backup.dialog.select

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.smasher.backup.dialog.BaseDialogFragment
import com.smasher.backup.dialog.R
import com.smasher.backup.dialog.databinding.FragmentSelectDelegateBinding
import com.smasher.backup.dialog.select.adapter.SelectAdapter
import com.smasher.backup.dialog.select.delegate.ElementShowDelegate
import com.smasher.backup.dialog.select.listener.OnSelectListener
import com.smasher.state.StateViewHelper

/**
 * baseSelectDialog
 *
 * @param <T>
 */
abstract class BaseSelectDialog<T : Any> : BaseDialogFragment(), View.OnClickListener {

    lateinit var mBinding: FragmentSelectDelegateBinding

    private val listeners: MutableList<OnSelectListener<T>> = mutableListOf()
    private val delegate by lazy {
        createShowDelegate()
    }

    val mList: MutableList<T> = mutableListOf()
    val mHelper by lazy { StateViewHelper(mBinding.container) }
    val mAdapter: SelectAdapter<T> by lazy {
        createAdapter(delegate)
    }

    var mode: SelectMode = SelectMode.SINGLE
        set(value) {
            field = value
            mAdapter.mode = value
            Log.d(TAG, "setMode: $value")
        }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        mBinding = FragmentSelectDelegateBinding.inflate(inflater, container, false)
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mHelper.stateLoading()
        mHelper.onReloadClickListener(reloadListener)


        mAdapter.setData(mList)
        mAdapter.mode = mode
        mBinding.recyclerView.adapter = mAdapter
        mBinding.recyclerView.layoutManager = LinearLayoutManager(context)

        mBinding.actionConfirm.setOnClickListener(this)
        mBinding.actionBack.setOnClickListener(this)

        mBinding.refreshLayout.setEnableRefresh(false)
        mBinding.refreshLayout.setEnableLoadMore(false)
    }


    fun setData(list: List<T>) {
        mList.clear()
        mList.addAll(list) // 合并为一次操作
    }

    /**
     * add select listener
     *
     * @param listener
     */
    fun addSelectListener(listener: OnSelectListener<T>) {
        listeners.add(listener)
    }

    /**
     * can use {@link ViewGroup.LayoutParams#MATCH_PARENT}
     * or {@link ViewGroup.LayoutParams#WRAP_CONTENT}
     * or exactly number
     */
    protected abstract fun getWidth(): Int

    /**
     * can use {@link ViewGroup.LayoutParams#MATCH_PARENT}
     * or {@link ViewGroup.LayoutParams#WRAP_CONTENT}
     * or exactly number
     */
    protected abstract fun getHeight(): Int

    /**
     * 创建Adapter
     *
     * @return SelectAdapter
     */
    protected abstract fun createAdapter(delegate: ElementShowDelegate<T>): SelectAdapter<T>

    /**
     * 创建展示代理
     * @return ElementShowDelegate
     */
    abstract fun createShowDelegate(): ElementShowDelegate<T>

    /**
     * reload
     */
    protected abstract fun reload()

    /**
     * reload listener
     */
    private val reloadListener = View.OnClickListener { reload() }

    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    override fun onClick(v: View) {
        when (v.id) {
            R.id.action_confirm -> confirmAction()
            else -> dismiss()
        }
    }

    protected open fun confirmAction() {
        val selected = mAdapter.getSelectList()
        if (selected.isEmpty()) return
        Log.d(TAG, "confirmAction: $selected")
        Log.d(TAG, "SelectMode: $mode")
        when (mode) {
            SelectMode.SINGLE -> {
                listeners.forEach { it.onSelectSingle(selected[0]) }
            }

            SelectMode.MULTI -> {
                listeners.forEach { it.onSelectMultiple(selected) }
            }
        }
        dismiss()
    }


    override fun onStart() {
        super.onStart()
        dialog?.window?.setLayout(getWidth(), getHeight())
    }

    override fun onDestroy() {
        super.onDestroy()
        listeners.clear()
    }

}